/*!
 * \file weblogic_jms.c
 *
 * \brief weblogic jms 数据包解析
 *
 * All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.\n
 *
 * \version 3.0
 * \author wuwk
 * \date 2016/01/28
 *
 */

#include <stdio.h>

#include "wls_parse_message.h"
#include "weblogic_jms.h"

#define WEBLOGIC_JMS_DESTINATIONIMPL       "RMI:weblogic.jms.common.DestinationImpl"
#define WEBLOGIC_JMS_SENDREQUEST           "RMI:weblogic.jms.frontend.FEProducerSendRequest"
#define WEBLOGIC_JMS_CONSUMER              "RMI:weblogic.jms.frontend.FEConsumerCreateRequest"
#define WEBLOGIC_JMS_BROWSER_REQ           "RMI:weblogic.jms.frontend.FEEnumerationNextElementRequest"
#define WEBLOGIC_JMS_BROWSER_RESP          "RMI:weblogic.jms.common.JMSEnumerationNextElementResponse"

/*!
 * 设置对齐
 *
 * \param *p_st_data           (Frbyte_Packet          数据)
 * \param u16_len              (uint16_t 长度)
 * \param i_alignment          (int 对齐单元)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *
 */
FR_STATIC int __set_alignment(Frbyte_Packet *p_st_data, uint16_t u16_len, int i_alignment)
{
    while ((u16_len % i_alignment) != 0)
    {
        if (bytebuff_skip(p_st_data, 1) == FR_FAIL)
            return FR_FAIL;
        u16_len++;
    }

    while (((u16_len + 2)% i_alignment) != 0)
    {
        if (bytebuff_skip(p_st_data, 1) == FR_FAIL)
            return FR_FAIL;
        u16_len++;
    }

    return FR_SUCC;
}

/*!
 * 对齐
 *
 * \param *p_st_data           (Frbyte_Packet          数据)
 * \param i_alignment          (int 对齐单元)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *
 */
FR_STATIC int __skip_utf_alignment(Frbyte_Packet *p_st_data, int i_alignment)
{
    uint32_t u32_len = 0;

    if (p_st_data == NULL)
        return FR_FAIL;

    if (bytebuff_peek_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN) == FR_FAIL)
        return FR_FAIL;

    if (u32_len != 0)
    {
        while ( (u32_len % i_alignment) != 0)
            u32_len++;

        bytebuff_skip(p_st_data, u32_len+4);
    }

    return FR_SUCC;
}

/*!
 * 解析dispatcherId,取得weblogic server名
 *
 * \param *p_st_data           (Frbyte_Packet          数据)
 * \param *p_st_session        (Wls_jms_session session)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *
 */
int __weblogic_get_server(Frbyte_Packet *p_st_data, Wls_jms_session *p_st_session)
{
    char *p_wls_server = NULL;
    uint8_t u8_char = 0;
    uint16_t u16_len = 0;

    if (p_st_data == NULL || p_st_session == NULL)
        return FR_FAIL;

    if (bytebuff_get_char(p_st_data, &u8_char) == FR_FAIL)
        return FR_FAIL;

    bytebuff_skip(p_st_data, 5);

    if (bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN) == FR_FAIL)
        return FR_FAIL;

    p_wls_server = (char *)frmalloc(u16_len + 1);
    if (p_wls_server == NULL)
        return FR_FAIL;

    if (bytebuff_get_bytes(p_st_data, p_wls_server, u16_len) == FR_FAIL)
    {
        frfree(p_wls_server);
        return FR_FAIL;
    }
    p_wls_server[u16_len] = '\0';

    while ((u16_len % 4) != 0)
    {
        u16_len++;
        bytebuff_skip(p_st_data, 1);
    }

    if (p_st_session->p_weblogic_server)
        frfree(p_st_session->p_weblogic_server);

    p_st_session->p_weblogic_server = frstrdup(p_wls_server);
    if (p_st_session->p_weblogic_server == NULL)
    {
        frfree(p_wls_server);
        return FR_FAIL;
    }

    bytebuff_skip(p_st_data, 4); //hashCode

    frfree(p_wls_server);

    return FR_SUCC;
}

/*!
 * 解析destination
 *
 * \param *p_st_data           (Frbyte_Packet          数据)
 * \param u16_flag             (uint16_t flag)
 * \param *p_st_jms            (Wls_jms_info weblogic jms结构体)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *
 */
FR_STATIC int __destination_analysis(Frbyte_Packet *p_st_data, uint16_t u16_flag, Wls_jms_info *p_st_jms)
{
    Wls_jms_session *p_st_session = NULL;
    uint16_t u16_len = 0;
    char *p_module_name = NULL;
    int i_type = 0;
    int i_flag = 0;

    if (p_st_data == NULL || p_st_jms == NULL || p_st_jms->p_st_session == NULL)
        return FR_FAIL;

    p_st_session = p_st_jms->p_st_session;

    i_type = (u16_flag & 0xF) >> 0 & 0xFF;
    // topic
    if (i_type == 2)
        p_st_jms->is_topic = 1;

    i_flag = (u16_flag & 0xF00) >> 8 & 0xFF;

    // JMS模块名长度
    if (bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN) == FR_FAIL)
        return FR_FAIL;

    p_module_name = (char *)frmalloc(u16_len + 1);
    if (p_module_name == NULL)
        return FR_FAIL;

    // JMS模块名
    if (bytebuff_get_bytes(p_st_data, p_module_name, u16_len) == FR_FAIL)
        goto err;

    p_module_name[u16_len] = '\0';

    // 添加到session
    if (p_st_session->p_jms_module)
        frfree(p_st_session->p_jms_module);

    p_st_session->p_jms_module = frstrdup(p_module_name);
    if (p_st_session->p_jms_module == NULL)
        goto err;

    frfree(p_module_name);
    bytebuff_skip(p_st_data, 6);

    // 长度
    if (bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN) == FR_FAIL)
        return FR_FAIL;
    bytebuff_skip(p_st_data, u16_len);

    if ((u16_flag & 0x2000) != 0)
    {
        // skip backendId and destinationId
        if (wls_backend_destination_id(p_st_data, p_st_jms->i_start_pos, 1) == FR_FAIL)
            return FR_FAIL;
    }

    if ((u16_flag & 0x4000) != 0)
    {
        // multicastAddress
        if (__skip_utf_alignment(p_st_data, 4) == FR_FAIL)
            return FR_FAIL;
        // port
        bytebuff_skip(p_st_data, 4);
    }

    if ((u16_flag & 0x8000) != 0)
    {
        if (__weblogic_get_server(p_st_data, p_st_session) == FR_FAIL)
            return FR_FAIL;
    }

    return FR_SUCC;

err:
    if (p_module_name)
        frfree(p_module_name);

    return FR_FAIL;
}

/*!
 * sub解析
 *
 * \param *p_st_jms           (Wls_jms_info          JMS数据)
 * \param *p_st_body_data     (Frreport_body_data 上报数据)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *
 */
FR_STATIC int __weblogic_consumer(Wls_jms_info *p_st_jms, Frreport_body_data *p_st_body_data)
{
    Wls_jms_session *p_st_session = NULL;
    char arr_title[64];
    int i_ret = 0;

    if (p_st_jms == NULL)
        return FR_FAIL;

    if (p_st_jms->is_topic)
    {
        if (p_st_jms->p_st_session == NULL)
            return FR_FAIL;

        p_st_session = p_st_jms->p_st_session;

        if (p_st_session->p_queue)
        {
            i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_SUB_QUE, p_st_session->p_queue);
            if (i_ret == FR_FAIL)
                return FR_FAIL;

            snprintf(arr_title, sizeof(arr_title), "SUB %s", p_st_session->p_queue);
            // title
            if (p_st_session->p_title == NULL)
            {
                p_st_session->p_title = frstrdup(arr_title);
                if (p_st_session->p_title == NULL)
                    return FR_FAIL;
            }

            p_st_jms->i_type = WLS_SUB;
        }
    }

    return FR_SUCC;
}

/*!
 * 服务器信息解析
 *
 * \param *p_st_jms           (Wls_jms_info          jms结构体)
 * \param *p_st_data          (Frbyte_Packet 数据)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *
 */
FR_STATIC int __weblogic_destination_impl(Wls_jms_info *p_st_jms, Frbyte_Packet *p_st_data)
{
    Wls_jms_session *p_st_session = NULL;
    uint16_t u16_flag = 0;
    uint16_t u16_len = 0;
    char *p_module_name = NULL;
    char *p_jms_server = NULL;
    char *p_queue = NULL;
    int i_ret = 0;

    if (p_st_jms == NULL || p_st_jms->p_st_session == NULL
        || p_st_data == NULL)
        return FR_FAIL;

    p_st_session = p_st_jms->p_st_session;

    if (bytebuff_get_short(p_st_data, 2, &u16_flag, BYTE_BIG_ENDIAN) == FR_FAIL)
        return FR_FAIL;

    if (__set_alignment(p_st_data, 0, 4) == FR_FAIL)
        return FR_FAIL;

    // JMS模块名长度+队列名
    if (bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN) == FR_FAIL)
        return FR_FAIL;

    p_module_name = (char *)frmalloc(u16_len + 1);
    if (p_module_name == NULL)
        return FR_FAIL;

    // JMS模块名
    if (bytebuff_get_bytes(p_st_data, p_module_name, u16_len) == FR_FAIL)
        goto err;

    p_module_name[u16_len] = '\0';

    // 队列名
    p_queue = strchr(p_module_name, '!');
    if (p_queue == NULL)
        goto err;

    if (p_st_session->p_queue)
        frfree(p_st_session->p_queue);

    // 添加到session
    p_st_session->p_queue = frstrdup(p_queue+1);
    if (p_st_session->p_queue == NULL)
        goto err;

    *p_queue = '\0';

    if (p_st_session->p_jms_module)
        frfree(p_st_session->p_jms_module);

    // 添加到session
    p_st_session->p_jms_module = frstrdup(p_module_name);
    if (p_st_session->p_jms_module == NULL)
        goto err;

    frfree(p_module_name);
    p_module_name = NULL;

    if (__set_alignment(p_st_data, u16_len, 4) == FR_FAIL)
        goto err;

    // JMS server长度
    if (bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN) == FR_FAIL)
        goto err;

    p_jms_server = (char *)frmalloc(u16_len + 1);
    if (p_jms_server == NULL)
        goto err;

    // JMS server名
    if (bytebuff_get_bytes(p_st_data, p_jms_server, u16_len) == FR_FAIL)
        goto err;

    p_jms_server[u16_len] = '\0';

    if (p_st_session->p_jms_server)
        frfree(p_st_session->p_jms_server);

    // 添加到session
    p_st_session->p_jms_server = frstrdup(p_jms_server);
    if (p_st_session->p_jms_server == NULL)
        goto err;

    frfree(p_jms_server);
    p_jms_server = NULL;

    if (__set_alignment(p_st_data, u16_len, 4) == FR_FAIL)
        return FR_FAIL;

    i_ret = __destination_analysis(p_st_data, u16_flag, p_st_jms);

    return i_ret;

err:
    if (p_module_name)
        frfree(p_module_name);

    if (p_jms_server)
        frfree(p_jms_server);

    return FR_FAIL;
}

/*!
 * iiop 浏览请求解析
 *
 * \param *p_st_session           (Wls_jms_session         JMS session数据)
 * \param *p_st_body_data         (Frreport_body_data    上报数据)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *
 */
FR_STATIC int __weblogic_browse_req(Wls_jms_session *p_st_session
                                  , Frreport_body_data *p_st_body_data)
{
    char arr_title[64];
    int i_ret = 0;

    if (p_st_session == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    // method上报
    i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_METHOD_REQ, "PEEK");
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    // title
    if (p_st_session->p_queue != NULL)
        snprintf(arr_title, sizeof(arr_title), "PEEK %s", p_st_session->p_queue);
    else
        snprintf(arr_title, sizeof(arr_title), "PEEK");

    if (p_st_session->p_title)
        frfree(p_st_session->p_title);

    p_st_session->p_title = frstrdup(arr_title);
    if (p_st_session->p_title == NULL)
        return FR_FAIL;

    return FR_SUCC;
}

/*!
 * iiop weblogic jms 浏览消息响应解析
 *
 * \param *p_st_jms            (Wls_jms_info  J       MS数据)
 * \param *p_st_data           (Frbyte_Packet         数据)
 * \param *p_st_body_data      (Frreport_body_data    上报数据)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *
 */
FR_STATIC int __weblogic_browse_resp(Wls_jms_info *p_st_jms
                                   , Frbyte_Packet *p_st_data
                                   , Frreport_body_data *p_st_body_data)
{
    char arr_size[64];
    uint8_t u8_msg_type = 0;
    uint8_t u8_flag = 0;
    int i_ret = 0;

    if (p_st_jms == NULL || p_st_data == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    bytebuff_skip(p_st_data, 2);
    // 消息类型
    if (bytebuff_get_char(p_st_data, &u8_msg_type) == FR_FAIL)
        return FR_FAIL;

    bytebuff_skip(p_st_data, 1);

    if (bytebuff_get_char(p_st_data, &u8_flag) == FR_FAIL)
        return FR_FAIL;

    while(((bytebuff_getPosition(p_st_data) - p_st_jms->i_start_pos) % 4) != 0)
        bytebuff_skip(p_st_data, 1);

    if ((u8_flag & 0x20) != 0)
        bytebuff_skip(p_st_data, 8);

    if ((u8_flag & 0x40) != 0)
    {
        if (__skip_utf_alignment(p_st_data, 4) == FR_FAIL)
            return FR_FAIL;
    }

    switch (u8_msg_type)
    {
        case WLS_MAPMESSAGE:
            i_ret = wls_analysis_mapmessage(p_st_data, p_st_body_data, (char *)APM_REPORT_KEY_RESP, 1, 1, p_st_jms->i_start_pos);
            if (i_ret == FR_FAIL)
                return FR_FAIL;
            break;
        case WLS_OBJMESSAGE:
        case WLS_STREAMMESSAGE:
        case WLS_BYTEMESSAGE:
            i_ret = wls_analysis_objmessage(p_st_data, p_st_body_data, (char *)APM_REPORT_KEY_RESP, 1, 1, p_st_jms->i_start_pos);
            if (i_ret == FR_FAIL)
                return FR_FAIL;
            break;
        case WLS_MESSAGE:
        case WLS_TEXTMESSAGE:
            i_ret = wls_analysis_textmessage(p_st_data, p_st_body_data, (char *)APM_REPORT_KEY_RESP, 1, 1, p_st_jms->i_start_pos);
            if (i_ret == FR_FAIL)
                return FR_FAIL;
            break;
        default:
            return FR_SUCC;
    }

    if (i_ret == APM_L7_ANALYZE_TODO)
        return APM_L7_ANALYZE_TODO;

    snprintf(arr_size, sizeof(arr_size), "response.%s", MQ_REPORT_MESSAGE_SIZE);
    // 消息个数上报
    i_ret = frreport_body_l7_add_int(p_st_body_data, arr_size, 1);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    if (bytebuff_remaining(p_st_data))
        bytebuff_skip(p_st_data, bytebuff_remaining(p_st_data));

    return FR_SUCC;
}

/*!
 * iiop weblogic jms 发送消息解析
 *
 * \param *p_st_jms            (Wls_jms_info          JMS数据)
 * \param *p_st_data           (Frbyte_Packet         数据)
 * \param *p_st_body_data      (Frreport_body_data    上报数据)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *
 */
FR_STATIC int __weblogic_send_message(Wls_jms_info *p_st_jms
                                    , Frbyte_Packet *p_st_data
                                    , Frreport_body_data *p_st_body_data)
{
    Wls_jms_session *p_st_session = NULL;
    char arr_title[64];
    int i_ret = 0;

    if (p_st_jms == NULL || p_st_jms->p_st_session == NULL
        || p_st_data == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    p_st_session = p_st_jms->p_st_session;

    // method上报
    i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_METHOD_REQ, "PUT");
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    if (p_st_session->p_title)
        frfree(p_st_session->p_title);

    if (p_st_session->p_queue != NULL)
    {
        // title
        snprintf(arr_title, sizeof(arr_title), "PUT %s", p_st_session->p_queue);
        p_st_session->p_title = frstrdup(arr_title);
        if (p_st_session->p_title == NULL)
            return FR_FAIL;

        // queue/topic
        if (p_st_jms->is_topic == 1)
            i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_REQ_TOPIC, p_st_session->p_queue);
        else
            i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_REQ_QUE, p_st_session->p_queue);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else
    {
        // title
        snprintf(arr_title, sizeof(arr_title), "PUT");
        p_st_session->p_title = frstrdup(arr_title);
        if (p_st_session->p_title == NULL)
            return FR_FAIL;
    }

    i_ret = wls_message_analysis(p_st_data, p_st_body_data, (char *)APM_REPORT_KEY_REQ, 1, p_st_jms->i_start_pos);

    return i_ret;
}

/*!
 * iiop weblogic jms 接收消息解析
 *
 * \param *p_st_jms            (Wls_jms_info          JMS数据)
 * \param *p_st_data           (Frbyte_Packet         数据)
 * \param *p_st_body_data      (Frreport_body_data    上报数据)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *
 */
FR_STATIC int __weblogic_push_message(Wls_jms_info *p_st_jms
                                    , Frbyte_Packet *p_st_data
                                    , Frreport_body_data *p_st_body_data)
{
    Wls_jms_session *p_st_session = NULL;
    char arr_title[64];
    int i_ret = 0;

    if (p_st_jms == NULL || p_st_jms->p_st_session == NULL
        || p_st_data == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    p_st_session = p_st_jms->p_st_session;

    if (p_st_session->p_title)
        frfree(p_st_session->p_title);

    if (p_st_session->p_queue != NULL)
    {
        // title
        snprintf(arr_title, sizeof(arr_title), "NOTIFY %s", p_st_session->p_queue);
        p_st_session->p_title = frstrdup(arr_title);
        if (p_st_session->p_title == NULL)
            return FR_FAIL;

        // queue/topic
        if (p_st_jms->is_topic == 1)
            i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_NOTIFY_TOPIC, p_st_session->p_queue);
        else
            i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_NOTIFY_QUE, p_st_session->p_queue);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else
    {
        // title
        snprintf(arr_title, sizeof(arr_title), "NOTIFY");
        p_st_session->p_title = frstrdup(arr_title);
        if (p_st_session->p_title == NULL)
            return FR_FAIL;
    }

    p_st_jms->i_type = WLS_NOTIFY;

    i_ret = wls_message_analysis(p_st_data, p_st_body_data, (char *)APM_REPORT_KEY_NOTIFY, 1, p_st_jms->i_start_pos);

    return i_ret;
}

/*!
 * iiop weblogic jms 请求解析
 *
 * \param *p_st_session_private        (corba_session         私有数据)
 * \param *p_st_data                   (Frbyte_Packet         数据)
 * \param *p_st_body_data              (Frreport_body_data    上报数据)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *
 */
int weblogic_jms_parse_req(corba_session *p_st_session_private
                         , Frbyte_Packet *p_st_data
                         , Frreport_body_data *p_st_body_data)
{
    Wls_jms_info *p_st_jms = NULL;
    Wls_jms_session *p_st_session = NULL;
    L7session_corba_private *p_st_private = NULL;
    uint32_t u32_len = 0;
    int i_idx = 0;

    if (p_st_session_private == NULL || p_st_data == NULL || p_st_body_data == NULL
        || p_st_session_private->p_st_private == NULL || p_st_session_private->p_st_jms == NULL)
        return FR_FAIL;

    p_st_private = p_st_session_private->p_st_private;
    p_st_jms = p_st_session_private->p_st_jms;

    if (p_st_jms->i_start_pos == 0)
        p_st_jms->i_start_pos = bytebuff_getPosition(p_st_data);

    if (bytebuff_memstr(p_st_data, bytebuff_getPosition(p_st_data), 0, WEBLOGIC_JMS_SENDREQUEST, strlen(WEBLOGIC_JMS_SENDREQUEST), &i_idx) == FR_SUCC)
    {
        // send message
        bytebuff_setPosition(p_st_data, i_idx - 4);
        if (bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN) == FR_FAIL)
            return FR_FAIL;

        while ( (u32_len % 4) != 0)
            u32_len++;

        bytebuff_skip(p_st_data, u32_len);
        bytebuff_skip(p_st_data, 8); // 长度+4

        if (__weblogic_send_message(p_st_jms, p_st_data, p_st_body_data) == FR_FAIL)
            return FR_FAIL;
    }
    else if (bytebuff_memstr(p_st_data, bytebuff_getPosition(p_st_data), 0, WEBLOGIC_JMS_CONSUMER, strlen(WEBLOGIC_JMS_CONSUMER), &i_idx) == FR_SUCC)
    {
        // sub
        if (__weblogic_consumer(p_st_jms, p_st_body_data) == FR_FAIL)
            return FR_FAIL;
    }
    else if (bytebuff_memstr(p_st_data, bytebuff_getPosition(p_st_data), 0, WEBLOGIC_JMS_BROWSER_REQ, strlen(WEBLOGIC_JMS_BROWSER_REQ), &i_idx) == FR_SUCC)
    {
        // browse request
        if (__weblogic_browse_req(p_st_jms->p_st_session, p_st_body_data) == FR_FAIL)
            return FR_FAIL;
    }

    if (p_st_jms->p_st_session == NULL)
        return FR_FAIL;

    p_st_session = p_st_jms->p_st_session;

    if (p_st_private->p_title != NULL && p_st_session->p_title != NULL)
        frfree(p_st_private->p_title);

    if (p_st_session->p_title != NULL)
    {
        p_st_private->p_title = frstrdup(p_st_session->p_title);
        if (p_st_private->p_title == NULL)
            return FR_FAIL;
    }

    p_st_jms->i_start_pos = 0;

    return FR_SUCC;
}

/*!
 * iiop weblogic jms 响应解析
 *
 * \param *p_st_session_private        (corba_session         私有数据)
 * \param *p_st_data                   (Frbyte_Packet         数据)
 * \param *p_st_body_data              (Frreport_body_data    上报数据)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *
 */
int weblogic_jms_parse_resp(corba_session *p_st_session_private
                          , Frbyte_Packet *p_st_data
                          , Frreport_body_data *p_st_body_data)
{
    Wls_jms_info *p_st_jms_info = NULL;
    Wls_jms_session *p_st_session = NULL;
    L7session_corba_private *p_st_private = NULL;
    uint32_t u32_len = 0;
    int i_idx = 0;
    int i_ret = 0;

    if (p_st_session_private == NULL || p_st_data == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    p_st_private = p_st_session_private->p_st_private;

    if (p_st_session_private->is_wls_jms == 0)
    {
        p_st_session_private->is_wls_jms = 1;

        p_st_jms_info = (Wls_jms_info *)frmalloc(sizeof(Wls_jms_info));
        if (p_st_jms_info == NULL)
            return FR_FAIL;
        memset(p_st_jms_info, 0x00, sizeof(Wls_jms_info));

        p_st_session_private->p_st_jms = p_st_jms_info;

        p_st_session = (Wls_jms_session *)frmalloc(sizeof(Wls_jms_session));
        if (p_st_session == NULL)
            return FR_FAIL;
        memset(p_st_session, 0x00, sizeof(Wls_jms_session));

        p_st_session_private->p_st_jms->p_st_session = p_st_session;

        if (bytebuff_memstr(p_st_data, bytebuff_getPosition(p_st_data), 0, WEBLOGIC_JMS_PUSHREQUEST, strlen(WEBLOGIC_JMS_PUSHREQUEST), &i_idx) != FR_SUCC)
            return FR_SUCC;
    }

    p_st_jms_info = p_st_session_private->p_st_jms;
    if (p_st_jms_info == NULL)
        return FR_FAIL;

    if (p_st_jms_info->i_start_pos == 0)
        p_st_jms_info->i_start_pos = bytebuff_getPosition(p_st_data);

    if (bytebuff_memstr(p_st_data, bytebuff_getPosition(p_st_data), 0, WEBLOGIC_JMS_PUSHREQUEST, strlen(WEBLOGIC_JMS_PUSHREQUEST), &i_idx) == FR_SUCC)
    {
        // push message
        bytebuff_setPosition(p_st_data, i_idx - 4);
        if (bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN) == FR_FAIL)
            return FR_FAIL;

        while ( (u32_len % 4) != 0)
            u32_len++;

        bytebuff_skip(p_st_data, u32_len);
        bytebuff_skip(p_st_data, 8); // 长度+4

        if (__weblogic_push_message(p_st_session_private->p_st_jms, p_st_data, p_st_body_data) == FR_FAIL)
            return FR_FAIL;
    }
    else if (bytebuff_memstr(p_st_data, bytebuff_getPosition(p_st_data), 0, WEBLOGIC_JMS_BROWSER_RESP, strlen(WEBLOGIC_JMS_BROWSER_RESP), &i_idx) == FR_SUCC)
    {
        // browse response
        bytebuff_setPosition(p_st_data, i_idx - 4);
        if (bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN) == FR_FAIL)
            return FR_FAIL;

        while ( (u32_len % 4) != 0)
            u32_len++;

        bytebuff_skip(p_st_data, u32_len);
        bytebuff_skip(p_st_data, 8); // 长度+4

        if (__weblogic_browse_resp(p_st_session_private->p_st_jms, p_st_data, p_st_body_data) == FR_FAIL)
            return FR_FAIL;
    }
    else if (bytebuff_memstr(p_st_data, bytebuff_getPosition(p_st_data), 0, WEBLOGIC_JMS_DESTINATIONIMPL, strlen(WEBLOGIC_JMS_DESTINATIONIMPL), &i_idx) == FR_SUCC)
    {
        bytebuff_setPosition(p_st_data, i_idx - 4);
        // skip WEBLOGIC_JMS_DESTINATIONIMPL
        if (__skip_utf_alignment(p_st_data, 4) == FR_FAIL)
            return FR_FAIL;

        bytebuff_skip(p_st_data, 6);

        i_ret = __weblogic_destination_impl(p_st_jms_info, p_st_data);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }

    if (p_st_jms_info->p_st_session == NULL)
        return FR_FAIL;

    p_st_session = p_st_jms_info->p_st_session;

    if (p_st_private->p_title != NULL && p_st_session->p_title != NULL)
        frfree(p_st_private->p_title);

    if (p_st_session->p_title != NULL)
        p_st_private->p_title = p_st_session->p_title;

    p_st_session->p_title = NULL;
    p_st_jms_info->i_start_pos = 0;

    return FR_SUCC;
}
